'''
Created on Sep 26, 2013

@author: dewey
'''
from PyQt4.QtCore import *
from PyQt4.QtGui import *
from geolib.geom2d import PointSeries, Polygon
import geolib.geomeasure as geomeasure
            
            
class ItemizedQGraphicsPixmapItem(QGraphicsPixmapItem):
    """Represents a QGraphicsPixmapItem in MapFrameLayer so that clicks can be directed back to
    the item's parent layer"""
    
    def __init__(self, layer, pxMap):
        super(ItemizedQGraphicsPixmapItem, self).__init__(pxMap)
        self.__layer = layer
        self.__id = None
    
    def setItemId(self, itemId):
        self.__id = itemId
        
    def itemId(self):
        return self.__id
    
    def contextMenuEvent(self, event):
        if self.__layer.itemsRightClickable():
            self.__layer.onItemContextMenu(self.itemId(), event)
            self.__layer.frame()._disableContextMenu()
        else:
            super(ItemizedQGraphicsPixmapItem, self).contextMenuEvent(event)
    
    def mousePressEvent(self, event):
        if event.button() == Qt.LeftButton and self.__layer.itemsClickable():
            pass
        else:
            super(ItemizedQGraphicsPixmapItem, self).mousePressEvent(event)
    
    def mouseReleaseEvent(self, event):
        self.__layer.frame().setCreateContextMenu(True) #reset just in case
        if event.button() == Qt.LeftButton and self.__layer.itemsClickable():
            self.__layer.onItemClick(self.itemId())
        else:
            super(ItemizedQGraphicsPixmapItem, self).mouseReleaseEvent(event)



class GraphicsLineStringItem(QGraphicsPathItem):
    
    def __init__(self, isPolygon=False, scene=None):
        super(GraphicsLineStringItem, self).__init__(None, scene)
        self.__path = QPainterPath()
        self.__series = PointSeries()
        self.__itemId = None
        self.__ispolygon = isPolygon
        
    def itemId(self):
        return self.__itemId
    
    def setItemId(self, itemId):
        self.__itemId = itemId
    
    def setIsPolygon(self, flag):
        self.__ispolygon = flag
        self.redraw()
    
    def isPolygon(self):
        return self.__ispolygon
    
    def series(self):
        return self.__series
    
    def polygon(self):
        return Polygon(self.series())
    
    def geoDistance(self, suggestLatLonPoint=None):
        if self.count() >= 2 or (self.count() == 1 and suggestLatLonPoint is not None):
            tempSeries = PointSeries(self.series())
            if suggestLatLonPoint is not None:
                tempSeries.append(suggestLatLonPoint)
            return geomeasure.distance(tempSeries)
        else:
            return 0
    
    def geoArea(self, suggestLatLonPoint=None):
        if self.count() >= 3 or (self.count() == 2 and suggestLatLonPoint is not None):
            tempSeries = PointSeries(self.series())
            if suggestLatLonPoint is not None:
                tempSeries.append(suggestLatLonPoint)
            return geomeasure.area(tempSeries)
        else:
            return 0
    
    def geoPerimeter(self, suggestLatLonPoint=None):
        if self.count() >= 2 or (self.count() == 1 and suggestLatLonPoint is not None):
            tempSeries = PointSeries(self.series())
            if suggestLatLonPoint is not None:
                tempSeries.append(suggestLatLonPoint)
            tempSeries.append(tempSeries[0])
            return geomeasure.distance(tempSeries)
        else:
            return 0
    
    def commitAll(self, pointsList, projection):
        for point in pointsList:
            scenePt = projection.scenePoint(point)
            self.__commit(point, scenePt, False)
        self.redraw()
    
    def commitInterior(self, pointsList, projection):
        if pointsList:
            self.__path.closeSubpath()
            self.__path.moveTo(projection.scenePoint(pointsList[0]))
            self.commitAll(pointsList, projection)
    
    def commitLatLon(self, latlon, projection):
        scenePt = projection.scenePoint(latlon)
        self.__commit(latlon, scenePt)
    
    def commitScenePoint(self, scenePt, projection):
        latlon = projection.latLonPoint(scenePt)
        self.__commit(latlon, scenePt)
    
    def __commit(self, latlon, scenePt, redraw=True):
        if self.count() > 0:
            self.__path.lineTo(scenePt)
        else:
            self.__path = QPainterPath(scenePt)
            
        self.series().append(latlon)
        if redraw:
            self.redraw()
    
    def redraw(self, path=None):
        if path is None:
            path = QPainterPath(self.__path)
        if self.isPolygon():
            path.closeSubpath()
        self.setPath(path)
    
    def finalize(self):
        self.__series = None
    
    def suggestLatLonPoint(self, latlon, projection):
        self.suggestScenePoint(projection.scenePoint(latlon))
    
    def suggestScenePoint(self, scenePt):
        tempPath = QPainterPath(self.__path)
        tempPath.lineTo(scenePt)
        self.redraw(tempPath)
    
    def clear(self):
        self.__path = QPainterPath()
        self.series().clear()
        self.redraw()
    
    def count(self):
        return self.series().count()